package com.fangwaii.core.socket.agreement;

import com.alibaba.fastjson.JSON;
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.Attribute;
import io.netty.handler.codec.http.multipart.FileUpload;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;

import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author lxc18
 * @date 2024/12/4 17:51
 * @description RequestParser,解析http请求，解析HTTP请求，GET/POST form-data\raw-json
 */
public class RequestParser {
    private final FullHttpRequest request;
    public String getUri() {
        String uri = request.uri();
        int idx = uri.indexOf("?");
        uri = idx > 0 ? uri.substring(0, idx) : uri;
        if (uri.equals("/favicon.ico")) return null;
        return uri;
    }
    public RequestParser(FullHttpRequest request) {
        this.request = request;
    }
    public Map<String, Object> parse(){
        //对request进行解析
        //获取请求类型，GET/POST
        HttpMethod method = request.method();
        //返回参数，http请求传入的参数
        Map<String, Object> parameterMap = new HashMap<>();
        if (method.equals(HttpMethod.GET)) {
            QueryStringDecoder decoder = new QueryStringDecoder(request.uri());
            Map<String, List<String>> parameters = decoder.parameters();
            for (Map.Entry<String, List<String>> entry : parameters.entrySet()) {
                String key = entry.getKey();
                List<String> values = entry.getValue();
                if (values.size() == 1) {
                    parameterMap.put(key, values.get(0));
                } else {
                    parameterMap.put(key, values);
                }
            }

        } else if (method.equals(HttpMethod.POST)) {

            try {
                // 获取 Content-Type
                String contentType = request.headers().get("Content-Type");

                // 根据 Content-Type 分别处理
                if (contentType.contains("application/json")) {
                    // 解析 JSON 格式
                    parameterMap = parseJson(request);
                } else if (contentType.contains("application/x-www-form-urlencoded")) {
                    // 解析表单格式
                    parameterMap = parseFormUrlEncoded(request);
                } else if (contentType.contains("multipart/form-data")) {
                    // 解析文件上传格式
                    parameterMap = parseMultipart(request);
                } else {
                    throw new RuntimeException("未实现的协议类型 Content-Type：" + contentType);
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("Failed to parse request: " + e.getMessage());
            }
        }
        return parameterMap;
    }
    // 解析 application/json
    private Map<String, Object> parseJson(FullHttpRequest request) throws Exception {
        ByteBuf content = request.content();
        String body = content.toString(StandardCharsets.UTF_8);
        return JSON.parseObject(body);
    }

    // 解析 application/x-www-form-urlencoded
    private Map<String, Object> parseFormUrlEncoded(FullHttpRequest request) {
        Map<String, Object> result = new HashMap<>();
        ByteBuf content = request.content();
        String body = content.toString(StandardCharsets.UTF_8);

        QueryStringDecoder decoder = new QueryStringDecoder(body, false);
        decoder.parameters().forEach((key, value) -> result.put(key, value.size() == 1 ? value.get(0) : value));
        return result;
    }

    // 解析 multipart/form-data
    private Map<String, Object> parseMultipart(FullHttpRequest request) throws Exception {
        Map<String, Object> result = new HashMap<>();

        HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(request);
        try {
            for (InterfaceHttpData data : decoder.getBodyHttpDatas()) {
                if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) {
                    // 普通表单字段
                    Attribute attribute = (Attribute) data;
                    result.put(attribute.getName(), attribute.getValue());
                } else if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) {
                    // 文件字段
                    FileUpload fileUpload = (FileUpload) data;
                    Map<String, Object> fileInfo = new HashMap<>();
                    fileInfo.put("filename", fileUpload.getFilename());
                    fileInfo.put("contentType", fileUpload.getContentType());
                    fileInfo.put("content", fileUpload.getByteBuf().toString(StandardCharsets.UTF_8)); // 示例读取为字符串
                    result.put(fileUpload.getName(), fileInfo);
                }
            }
        } finally {
            decoder.destroy(); // 释放资源
        }
        return result;
    }
}
